<?php
/**
* @name AXXIS FRAMEWORK BOOTSTRAP
* @author Chris Michaelides <chris@axxis.gr>
* @link http://www.axxis.gr
* @copyright  Copyright (C) AXXIS INTERNET SOLUTIONS / All rights reserved.
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
*/
/**
 * This file is part of
 * AXXIS JOOMLA SOLUTIONS
 *
 * is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 2 of the License.
 *
 * is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with . If not, see <http://www.gnu.org/licenses>.
 */
 ?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://www.w3resource.com/twitter-bootstrap/twitter-bootstrap-v2/js/bootstrap-tooltip.js"></script>
<script src="http://www.w3resource.com/twitter-bootstrap/twitter-bootstrap-v2/js/bootstrap-popover.js"></script>
        <?php
class AFB {
    /**
     * General guide...
     * 
     * The default Bootstrap grid system utilizes 12 columns, making for a 940px wide container without responsive features enabled. 
     * With the responsive CSS file added, the grid adapts to be 724px and 1170px wide depending on your viewport. 
     * Below 767px viewports, the columns become fluid and stack vertically.
     * 
     * FLUID SYSTEM (uses the whole screen with percentage) 
     * 
     * CONTAINER: Provides a common fixed-width (and optionally responsive) layout with only <div class="container"> required.
     * Create a fluid container with <div class="container-fluid">
     * 
     * ROW, SPAN: For a simple two column layout, create a .row and add the appropriate number of .span* columns. 
     * As this is a 12-column grid, each .span* spans a number of those 12 columns, and should always add up to 12 for each row (or the number of columns in the parent).
     * Make any row "fluid" by changing .row to .row-fluid. 
     * 
     * OFFSET: Move columns to the right using .offset* classes. 
     * Each class increases the left margin of a column by a whole column. For example, .offset4 moves .span4 over four columns.
     * 
     * NESTING: To nest your content with the default grid, add a new .row and set of .span* columns within an existing .span* column. 
     * Nested rows should include a set of columns that add up to the number of columns of its parent.
     * THIS IS WRONG! We cannot always know the columns of the parent. Bootstrap 3 takes care of this.
     * Fluid grids utilize nesting differently: each nested level of columns should add up to 12 columns. 
     * This is because the fluid grid uses percentages, not pixels, for setting widths.
     * 
     * Turn on responsive CSS in your project by including the proper meta tag and additional stylesheet within the <head> of your document. 
     *     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     *     <link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
     * Bootstrap doesn't include responsive features by default at this time as not everything needs to be responsive. 
     * Instead of encouraging developers to remove this feature, we figure it best to enable it as needed.
     * 
     * VISIBILLITY BASED ON DEVICE:
     * .visible-phone
     * .visible-tablet
     * .visible-desktop
     * .hidden-phone
     * .hidden-tablet
     * .hidden-desktop
     * 
     * MISCELLANEOUS:
     * .pull-left   Float an element left
     * .pull-right  Float an element right
     * .muted       Change an element's color to #999
     * .clearfix    Clear the float on any element
     * 
     */

/*==============================================================================
 * ROWS
==============================================================================*/
    /**
     * Returns a complete Bootstrap row
     * 
     * @param type $spans    = spans, eg. "span10 suite-box"=>"Lorem Ipsum", "span2"=>"Bla Bla"
     * @param type $rowclass = class of the row
     * @return string
     */
    static function row($spans,$rowclass='') {
        $return = '<div class="row '.$rowclass.'">';
        foreach ($spans as $key => $content) {
            $return.= '<div class="'.$key.'">';
            $return.= $content;
            $return.= '</div>';
        }
        $return.= '</div>';
        
        return $return;
    }
    
/*==============================================================================
 * HEADINGS
==============================================================================*/
    /**
     * Headings
     * 
     * @param type $type    = the type of heading (1,2,3,4,5,6)
     * @param type $content = the content of heading
     * @param string $class = the class of heading
     * @return type
     */
    static function heading($type,$content,$class='') {
        if ($class) $class = ' class="'.$class.'"';
        return '<h'.$type.$class.'>'.$content.'</h'.$type.'>';
    }
    
    /**
     * 
     * @param type $content
     * @param type $class
     * @return type
     */
    static function hero_unit($content,$class) {
        return '<div class="hero-unit '.$class.'">'.$content.'</div>';
    }
    
    /**
     * 
     * @param type $content
     * @param type $class
     * @return type
     */
    static function page_header($content,$class) {
        return '<div class="page-header '.$class.'"><h1>'.$content.'</h1></div>';
    }
    
/*==============================================================================
 * IMAGES
==============================================================================*/
    /**
     * 
     * @param type $src
     * @param string $width
     * @param string $height
     * @param type $id
     * @param type $class
     * CAN BE (among others):
     * img-rounded  : rounded edges (140x140)
     * img-circle   : circle image  (140x140)
     * img-polaroid : double-frame, inner frame white (140x140)
     * 
     * @return type
     */
    static function image($src,$width='',$height='',$id='',$class='') {
        if (!empty($width))  {
            if (is_numeric($width)) $width.= 'px';
            $width  = 'width:'.$width.';';
        }
        if (!empty($height)) {
            if (is_numeric($height)) $height.= 'px';
            $height = 'height:'.$height.';';
        }
        if (!empty($width) || !empty($height)) $style = 'style="'.$width.$height.'"'; else $style='';
        return '<img id="'.$id.'" name="'.$id.'" src="'.$src.'" '.$style.' class="'.$class.'">';
    }
    
/*==============================================================================
 * LINKS
==============================================================================*/
    /**
     * 
     * @param type $href
     * @param type $content
     * @param type $id
     * @param type $class
     * @return type
     */
    static function link($href,$content,$id='',$class='') {
        return '<a id="'.$id.'" name="'.$id.'" href="'.$href.'" class="'.$class.'">'.$content.'</a>';
    }
    
/*==============================================================================
 * ICONS
==============================================================================*/
    /**
     * 
     * @param type $type
     * See types here: http://getbootstrap.com/2.3.2/base-css.html#icons
     * Ommit "icon-"
     * 
     * @param type $white
     * @return type
     */
    static function icon($type,$white=false) {
        $white = $white ? ' icon-white' : '';
        return '<i class="icon-'.$type.$white.'"></i>';
    }
    
/*==============================================================================
 * PARAGRAPHS
==============================================================================*/
    /**
     * 
     * @param type $content
     * @param string $class
     * CAN BE:
     * text-left    = align-left
     * text-center  = align-center
     * text-right   = align-right
     * AND:
     * muted        = greyed out
     * text-warning = yellow
     * text-error   = red
     * text-info    = blue
     * text-success = green
     * 
     * together with your own classes
     * 
     * @return type
     */
    static function paragraph($content,$class='') {
        if ($class) $class = ' class="'.$class.'"';
        return '<p'.$class.'>'.$content.'</p>';
    }

    /**
     * 
     * @param type $content
     * @param string $class
     * CAN BE:
     * text-left    = align-left
     * text-center  = align-center
     * text-right   = align-right
     * AND:
     * muted        = greyed out
     * text-warning = yellow
     * text-error   = red
     * text-info    = blue
     * text-success = green
     * 
     * together with your own classes
     * 
     * @return type
     */
    static function paragraph_Strong($content,$class='') {
        return '<p class="lead '.$class.'">'.$content.'</p>';
    }

/*==============================================================================
 * CONTENT STYLES
==============================================================================*/
    /**
     * For de-emphasizing inline or blocks of text, use the small tag.
     * 
     * @param type $content
     * @param string $class
     * @return type
     */
    static function small($content,$class='') {
        if ($class) $class = ' class="'.$class.'"';
        return '<small'.$class.'>'.$content.'</small>';
    }

    /**
     * For emphasizing a snippet of text with a heavier font-weight.
     * 
     * @param type $content
     * @param string $class
     * @return type
     */
    static function strong($content,$class='') {
        if ($class) $class = ' class="'.$class.'"';
        return '<strong'.$class.'>'.$content.'</strong>';
    }

    /**
     * For emphasizing a snippet of text with italics.
     * 
     * @param type $content
     * @param string $class
     * @return type
     */
    static function italic($content,$class='') {
        if ($class) $class = ' class="'.$class.'"';
        return '<em'.$class.'>'.$content.'</em>';
    }

    /**
     * Abbreviation of bigger text
     * 
     * @param type $content = the abbreviation
     * @param type $title   = the text on hover
     * @return type
     */
    static function abbreviation($content,$title) {
        return '<abbr title="'.$title.'">'.$content.'</abbr>';
    }

    /**
     * Present contact information
     * 
     * @param type $content
     * @param string $class
     * @return type
     */
    static function address($content,$class='') {
        if ($class) $class = ' class="'.$class.'"';
        return '<address'.$class.'>'.$content.'</address>';
    }

    /**
     * For quoting blocks of content
     * 
     * @param type $content
     * @param string $class
     * @return type
     */
    static function quote($content,$class='') {
        if ($class) $class = ' class="'.$class.'"';
        return '<blockquote'.$class.'>'.$content.'</blockquote>';
    }

    /**
     * For quoting blocks of content, right-aligned
     * 
     * @param type $content
     * @param string $class
     * @return type
     */
    static function quote_Right($content,$class='') {
        return AFB::quote($content,'pull-right '.$class);
    }

    /**
     * Wrap INLINE snippets of code
     * 
     * @param type $content
     * @param string $class
     * @return type
     */
    static function code($content,$class='') {
        if ($class) $class = ' class="'.$class.'"';
        return '<code'.$class.'>'.$content.'</code>';
    }

    /**
     * Basic block (for multiple lines of code), with a max-height of 350px and a y-axis scrollbar.
     * 
     * @param type $content
     * @param type $class
     * @return type
     */
    static function pre($content,$class='') {
        return '<pre class="pre-scrollable '.$class.'>'.$content.'</pre>';
    }

/*==============================================================================
 * LISTS
==============================================================================*/
    /**
     * A list of items in which the order does not explicitly matter.
     * 
     * @param type $items   : Array of items containing [text], [style]
     * STYLE CAN BE:
     * disabled
     * nav-header : to make this an unclickable title
     * active     : to indicate the currently active item
     * divider
     * divider-vertical
     * dropdown   : to show like a dropdown button
     * 
     * @param string $class
     * @param type $numeric
     * @return string
     */
    static function list_bulletin($items,$class='',$numeric=false) {
        if ($class) $class = ' class="'.$class.'"';
        if ($numeric) $ul = 'ol'; else $ul = 'ul';
        $return = '<'.$ul.$class.'>';
        if (!empty($items)) {
            for ($i=0;$i<count($items);$i++) {
                $item = $items[$i];
                if (!empty($item->style))   $item->style=' class="'.$item->style.'"';
                else $item->style='';
                $return.= '<li '.$item->style.'>'.$item->text.'</li>';
            }
        }
        $return.= '</'.$ul.'>';
        
        return $return;
    }

    /**
     * A list of items in which the order does explicitly matter.
     * 
     * @param type $items   : Array of items containing [title] and [active] to indicate the currently active item
     * @param type $class
     * @return type
     */
    static function list_numeric($items,$class='') {
        return AFB::list_bulletin($items,$class,true);
    }

    /**
     * Remove the default list-style and left padding on list items (immediate children only).
     * 
     * @param type $items   : Array of items containing [title] and [active] to indicate the currently active item
     * @param type $class
     * @return type
     */
    static function list_plain($items,$class='') {
        return AFB::list_bulletin($items,'unstyled '.$class);
    }

    /**
     * Place all list items on a single line with inline-block and some light padding.
     * 
     * @param type $items   : Array of items containing [title] and [active] to indicate the currently active item
     * @param type $class
     * @return type
     */
    static function list_horizontal($items,$class='') {
        return AFB::list_bulletin($items,'inline '.$class);
    }

    /**
     * A list of terms with their associated descriptions.
     * 
     * @param type $titles  = array("Title",array("Item1","Item2",...))
     * @param string $class = class of list
     * @return string
     */
    static function list_with_descriptions($titles,$class='') {
        $count=1;
        if ($class) $class = ' class="'.$class.'"';
        $return = '<dl'.$class.'>';
        foreach ($titles as $title) {
            $return.= '<dt>'.$title->title.'</dt>';
            foreach ($title->items as $item) {
                $item = strstr($item,'class="') ? str_replace('class="','class="small ',$item,$count) : '<small>'.$item.'</small>';
                $return.= '<dd>'.$item.'</dd>';
            }
        }
        $return.= '</dl>';
        
        return $return;
    }

    /**
     * Make terms and descriptions in line up side-by-side.
     * 
     * @param type $titles
     * @param type $items
     * @param type $class
     * @return type
     */
    static function list_with_descriptions_Horizontal($titles,$items,$class='') {
        return AFB::list_with_descriptions($titles,$items,"dl-horizontal ".$class);
    }

/*==============================================================================
 * TABLES
==============================================================================*/
    /**
     * 
     * @param type $headcolumns = Header Columns
     * @param type $rows        = Array of rows containing: 
     * a)STYLE:
     * 'success' = green row
     * 'error'   = red row
     * 'warning' = green row
     * 'info'    = blue row
     * b)COLUMNS: the columns inside the row
     * @param type $class       = Class of the table.
     * Can be, among our own: 
     * "table-striped"      = Adds zebra-striping to any table row within the <tbody> via the :nth-child CSS selector (not available in IE7-8).
     * "table-bordered"     = Add borders and rounded corners to the table.
     * "table-hover"        = Enable a hover state on table rows within a <tbody>.
     * "table-condensed"    = Makes tables more compact by cutting cell padding in half.
     * And combinations.
     * @param type $caption     = Caption (description) of the table
     * @return string
     */
    static function table($headcolumns,$rows,$class='',$caption='') {
        $return = '<table class="table '.$class.'">';
        if ($caption) $return.= '<caption>'.$caption.'</caption>';
        if (count($headcolumns)>0) {
            $return.= '<thead><tr>';
            foreach ($headcolumns as $column) {
                $return.= '<th>'.$column.'</th>';
            }
            $return.= '</tr></thead>';
        }
        foreach ($rows as $row) {
            if (!empty($row->style)) $row->style = ' class="'.$row->style.'"';
            $return.= '<tr'.$row->style.'>';
            foreach ($row->columns as $column) {
                $return.= '<td>'.$column.'</td>';
            }
            $return.= '</tr>';
        }
        $return.= '</table>';
        
        return $return;
    }

    /**
     * Adds zebra-striping to any table row within the <tbody> via the :nth-child CSS selector (not available in IE7-8).
     * 
     * @param type $headcolumns
     * @param type $rows
     * @param type $class
     * @param type $caption
     * @return type
     */
    static function table_Striped($headcolumns,$rows,$class='',$caption='') {
        return AFB::table($headcolumns,$rows,'table-striped '.$class,$caption);
    }

    /**
     * Add borders and rounded corners to the table.
     * 
     * @param type $headcolumns
     * @param type $rows
     * @param type $class
     * @param type $caption
     * @return type
     */
    static function table_Bordered($headcolumns,$rows,$class='',$caption='') {
        return AFB::table($headcolumns,$rows,'table-bordered '.$class,$caption);
    }

    /**
     * Enable a hover state on table rows within a <tbody>.
     * 
     * @param type $headcolumns
     * @param type $rows
     * @param type $class
     * @param type $caption
     * @return type
     */
    static function table_Hovered($headcolumns,$rows,$class='',$caption='') {
        return AFB::table($headcolumns,$rows,'table-hover '.$class,$caption);
    }

    /**
     * Makes tables more compact by cutting cell padding in half.
     * 
     * @param type $headcolumns
     * @param type $rows
     * @param type $class
     * @param type $caption
     * @return type
     */
    static function table_Compact($headcolumns,$rows,$class='',$caption='') {
        return AFB::table($headcolumns,$rows,'table-condensed '.$class,$caption);
    }
    
/*==============================================================================
 * FORMS
==============================================================================*/
    /**
     * 
     * @param type $form_objects
     * 
     * @param string $class
     * CAN BE (among others):
     * form-search      = Add .form-search to the form and .search-query to the <input> for an extra-rounded text input.
     * form-inline      = Add .form-inline for left-aligned labels and inline-block controls for a compact layout.
     * form-horizontal  = Right align labels and float them to the left to make them appear on the same line as controls. Requires the most markup changes from a default form:
     *     Add .form-horizontal to the form
     *     Wrap labels and controls in .control-group
     *     Add .control-label to the label
     *     Wrap any associated controls in .controls for proper alignment
     * 
     * @return type
     */
    static function form($form_objects,$class) {
        if ($class) $class = ' class="'.$class.'"';
        $return = '<form'.$class.'><fieldset>';
        foreach ($form_objects as $object) {
            $return.= $object;
        }
        $return.= '</fieldset></form>';
    }

    /**
     * 
     * @param type $content
     * @param type $class
     * @return string
     */
    static function form_Search($content,$class) {
        $return = '<form class="form-search '.$class.'">';
        $return.= '<input type="text" name="search" class="input-medium search-query">';
        $return.= $content;
        $return.= '<button type="submit" class="btn">'.AFL::_("Search").'</button>';
        $return.= '</form>';
        
        return $return;
    }
    
    /**
     * 
     * @param type $form_objects
     * @param type $class
     * @return type
     */
    static function form_Inline($form_objects,$class) {
        return AFB::form($form_objects,'form-inline '.$class);
    }

    /**
     * 
     * @param type $form_objects
     * @param string $class
     * @return type
     */
    static function form_Horizontal($form_objects,$class) {
        return AFB::form($form_objects,'form-horizontal '.$class);
    }
    
    /**
     * 
     * @param type $label
     * @param type $type
     * @param type $id
     * @param type $value
     * @param type $placeholder
     * @param type $class       = class of the input
     * CAN BE (among others):
     * span1-12
     * input-block-level (takes up all horizontal space)
     * input-mini
     * input-small
     * input-medium
     * input-large
     * input-xlarge
     * input-xxlarge
     * 
     * @param type $helptext
     * @param type $typeahead   = an array of possible values of a text input. Values are listed while typing
     * @param type $editable    = default true
     * @param type $required    = default false
     * @param type $disabled    = default false
     * @param type $state       = warning (yellow), error (red), info (blue), success (green), or nothing
     * @param type $horizontal  = default false
     * @param type $inline      = Inline checkboxes. Add the .inline class to a series of checkboxes or radios for controls appear on the same line.
     * @param type $prepend     = Add text or buttons before any text-based input. Do note that select elements are not supported here.
     * @param type $append      = Add text or buttons after any text-based input. Do note that select elements are not supported here.
     * @return string
     */
    static function input($label,$type,$id,$value,$placeholder='',$class='',$helptext='',$extras='',$typeahead='',$editable=true,$required=false,$disabled=false,$state='',$horizontal=false,$inline=false,$prepend='',$append='') {
        $disabled       = $disabled ? 'disabled' : '';
        $required       = $required ? 'required' : '';
        $editable       = $editable ? '' : 'uneditable-input';
        $inline         = $inline ? ' inline' : '';
        $label_class    = ' class="'.$type.$inline.'" ';
        $label_for      = '';
        $prepend_class  = empty($prepend) ? '' : 'input-prepend';
        $append_class   = empty($append) ? '' : 'input-append';
        $return         = '';

        if (is_array($typeahead)) {
            $data_source = '[';
            foreach ($typeahead as $item) {
                $data_source.= '"'.$item.'",';
            }
            $data_source = substr($data_source, 0, -1).']';
            $typeahead = 'data-source="'.$data_source.'" data-items="4" data-provide="typeahead" style="margin: 0 auto;"';
        }
        if ($horizontal) {
            $return.= '<div class="control-group '.$state.'">';
            $label_class = str_replace('class="','class="control-label ',$label_class);
            $label_for   = ' for="'.$id.'" ';
        }
        if ($horizontal && $type!='text') $return.= '<div class="controls controls-row">';
        if (!empty($label)) {
            $return.= '<label id="'.$id.rand().'"'.$label_class.$label_for.'>';
            $return.= $label;
            if ($type=='text') $return.= '</label>';
        }

        if ($horizontal && $type=='text') $return.= '<div class="controls">';
        if (!empty($prepend) || !empty($append)) $return.= '<div class="'.$prepend_class.' '.$append_class.'">';
        if (!empty($prepend)) {
            if (!strstr($prepend,'<button')) $return.= '<span class="add-on">'.$prepend.'</span>';
            else $return.= $prepend;
        }
        $return.= '<input class="'.$class.' '.$editable.'" type="'.$type.'" '.$typeahead.' '.$extras.' id="'.$id.'" name="'.$id.'" placeholder="'.$placeholder.'" value="'.$value.'" '.$required.' '.$disabled.'>';
        if (!empty($append)) {
            if (!strstr($append,'<button')) $return.= '<span class="add-on">'.$append.'</span>';
            else $return.= $append;
        }
        if (!empty($prepend) || !empty($append)) $return.= '</div>';
        if ($horizontal && $type=='text') $return.= '</div>';
        
        if (!empty($label) && $type!='text') $return.= '</label>';
        
        if (!empty($helptext)) $return.= '<span class="help-block">'.$helptext.'</span>';
        
        if ($horizontal && $type!='text') $return.= '</div>';
        if ($horizontal) $return.= '</div>';
        
        return $return;
    }
    
    /**
     * 
     * @param type $label
     * @param type $type
     * @param type $id
     * @param type $value
     * @param type $rows
     * @param type $helptext
     * @param type $horizontal
     * @return string
     */
    static function textarea($label,$id,$value='',$rows=3,$helptext='',$horizontal=false) {
        $label_class    = ' class="textarea" ';
        $label_for      = '';
        $return         = '';

        if ($horizontal) {
            $return.= '<div class="control-group">';
            $label_class = str_replace('class="','class="control-label ',$label_class);
            $label_for   = ' for="'.$id.'" ';
        }
        if (!empty($label)) $return.= '<label'.$label_class.$label_for.'>'.$label.'</label>';

        if ($horizontal) $return.= '<div class="controls">';
        $return.= '<textarea id="'.$id.'" name="'.$id.'" rows="'.$rows.'">'.$value.'</textarea>';
        if ($horizontal) $return.= '</div>';
        
        if (!empty($helptext)) $return.= '<span class="help-block">'.$helptext.'</span>';
        
        if ($horizontal) $return.= '</div>';
        
        return $return;
    }
    
    /**
     * The Form actions: submit, cancel, etc.
     * 
     * @param type $buttons : array of buttons(pre-rendered content)
     * @param type $class
     * @return string
     */
    static function form_actions($buttons,$class) {
        $return = '<div class="form-actions '.$class.'">';
        foreach ($buttons as $button) {
            $return.= $button;
        }
        $return.= '</div>';
        
        return $return;
    }
    
    /**
     * 
     * @param type $params = array([size],[id],[name],[class],[width],[onchange],[options]);
     * @return string
     */
    static function select($params, $placeholder='', $chosen=true) {
      $size       = $params['size'];
      $id         = $params['id'];
      $name       = $params['name'];
      $class      = $params['class'];
      $width      = $params['width'];
      $onchange   = $params['onchange'];
      $options    = $params['options'];

      if (!empty($placeholder)) $placeholder = 'data-placeholder="'.$placeholder.'"';
      $tree = '<select class="inputbox '.$class.'" size="'.$size.'" id="'.$id.'" name="'.$name.'" width="'.$width.'" onChange="'.$onchange.'" '.$placeholder.'>';
      $tree.= $options;
      $tree.= '</select>&nbsp;&nbsp;&nbsp;&nbsp;';
      
      if ($chosen) {
        ?>
        <script>
        $(function ()
        { $("#<?php echo $id; ?>").chosen({
                    disable_search_threshold: 10,
                    placeholder: '<?php echo $placeholder; ?>'
                });
        });
        </script>
        <?php
      }
      return $tree;
    }

    /**
     * 
     * @param type $id
     * @param type $title
     * @param type $onclick : add an "onclick" action...
     * @param type $link    : ..or alternative a link to navigate upon clicking
     * @param type $loading : to use a loading state on a button when clicked
     * 
     * @param type $class
     * CAN BE (among others): 
     * btn-primary  : Provides extra visual weight and identifies the primary action in a set of buttons (dark blue)
     * btn-info     : Used as an alternative to the default styles (light blue)
     * btn-success  : Indicates a successful or positive action (green)
     * btn-warning  : Indicates caution should be taken with this action (yellow)
     * btn-danger   : Indicates a dangerous or potentially negative action (red)
     * btn-inverse  : Alternate dark gray button, not tied to a semantic action or use (black with white font)
     * btn-link     : Deemphasize a button by making it look like a link while maintaining button behavior (link)
     * AND:
     * btn-block
     * btn-large
     * btn-small
     * btn-mini
     * AND:
     * active
     * disabled
     * 
     * @return type
     */
    static function button($id,$title,$onclick='',$link='',$loading='',$class='') {
        if (!empty($onclick)) $onclick = 'onclick="'.$onclick.'"';
        if (!empty($loading)) $loading = 'data-loading-text="'.$loading.'"';
        if (!empty($link))    $buttontype = 'a href="'.$link.'"'; else $buttontype = 'button';
        $return = '<'.$buttontype.' class="btn '.$class.'" id="'.$id.'" name="'.$id.'" type="button" '.$loading.' '.$onclick.'>'.$title;
        $return.= $buttontype=='button' ? '</button>' : '</a>';
        return $return;
    }
    
    /**
     * 
     * @param type $id
     * @param type $title
     * 
     * @param type $class
     * CAN BE (among others): 
     * btn-primary  : Provides extra visual weight and identifies the primary action in a set of buttons (dark blue)
     * btn-info     : Used as an alternative to the default styles (light blue)
     * btn-success  : Indicates a successful or positive action (green)
     * btn-warning  : Indicates caution should be taken with this action (yellow)
     * btn-danger   : Indicates a dangerous or potentially negative action (red)
     * btn-inverse  : Alternate dark gray button, not tied to a semantic action or use (black with white font)
     * btn-link     : Deemphasize a button by making it look like a link while maintaining button behavior (link)
     * AND:
     * btn-block
     * btn-large
     * btn-small
     * btn-mini
     * AND:
     * active
     * disabled
     * 
     * @return type
     */
    static function button_Submit($id,$title,$class='') {
        return '<button class="btn '.$class.'" id="'.$id.'" name="'.$id.'" type="submit">'.$title.'</button>';
    }
    
    /**
     * creates a button with title and a dropdown menu. If you don't give a title, only the dropdown menu will be shown
     * 
     * @param type $id
     * @param type $title
     * @param type $dropdown    : Dropdown items (array) which hold [link] and [title]
     * 
     * @param type $class
     * CAN BE (among others): 
     * btn-primary  : Provides extra visual weight and identifies the primary action in a set of buttons (dark blue)
     * btn-info     : Used as an alternative to the default styles (light blue)
     * btn-success  : Indicates a successful or positive action (green)
     * btn-warning  : Indicates caution should be taken with this action (yellow)
     * btn-danger   : Indicates a dangerous or potentially negative action (red)
     * btn-inverse  : Alternate dark gray button, not tied to a semantic action or use (black with white font)
     * btn-link     : Deemphasize a button by making it look like a link while maintaining button behavior (link)
     * AND:
     * btn-block
     * btn-large
     * btn-small
     * btn-mini
     * AND:
     * active
     * disabled
     * @param type $dropup  : makes the dropdown face upwards
     * 
     * @return string
     */
    static function button_Dropdown($id,$title,$dropdown,$class='',$dropup=false) {
        $dropup = $dropup ? ' dropup' : '';
        $return = '<div class="btn-group'.$dropup.'">';
        $return.= '<button class="btn dropdown-toggle '.$class.'" id="'.$id.'" name="'.$id.'" data-toggle="dropdown">'.$title.'<span class="caret"></span></button>';
        $return.= '<ul class="dropdown-menu">';
        foreach ($dropdown as $item) {
            $return.= '<li onselect="'.$item->link.'">'.$item->title.'</li>';
        }
        $return.= '</ul>';
        $return.= '</div>';
        
        return $return;
    }
    
    /**
     * 
     * @param type $buttons
     * @param type $class
     * CAN BE(among others):
     * btn-group-vertical   : to create a vertical button group
     * @return string
     */
    static function button_group($buttons,$class='') {
        $return = '<div class="btn-group '.$class.'">';
        foreach ($buttons as $button) {
            $return.= $button;
        }
        $return.= '</div>';
        
        return $return;
    }
    
    /**
     * 
     * @param type $button_groups
     * @param type $class
     * @return string
     */
    static function button_toolbar($button_groups,$class='') {
        $return = '<div class="btn-toolbar '.$class.'">';
        foreach ($button_groups as $button_group) {
            $return.= $button_group;
        }
        $return.= '</div>';
        
        return $return;
    }
    
    /**
     * 
     * @param type $items   : list items. If "divider" it will create a horizontal dividing line. If "disabled:...." it will create a disabled link
     * @param type $class
     * CAN BE (among others):
     * pull-right   : to right align the dropdown menu
     * @param type $div     : if true, it will wrap the menu in a div (needed for top-level menus, not for sub-menus
     * @return string
     */
    static function dropdown_menu($items,$class='',$div=true) {
        if ($div) $return = '<div class="dropdown">';
        $return = '<ul class="drowpdown-menu '.$class.'" role="menu" aria-labelledby="dropdownMenu">';
        foreach ($items as $item) {
            if (is_array($item)) {
                $return.= '<li class="dropdown-submenu">'.str_replace('<a','<a tabindex="-1"',$item[0]);
                $return.= AFB::dropdown_menu($item,'',false);
                $return.= '</li>';
            }
            if ($item=='divider') $return.= '<li class="divider"></li>';
            elseif (strstr($item,'disabled:'))
                    $return.= '<li class="disabled">'.str_replace('<a','<a tabindex="-1"',$item).'</li>';
            else
                    $return.= '<li>'.str_replace('<a','<a tabindex="-1"',$item).'</li>';
        }
        $return.= '</ul>';
        if ($div) $return.= '</div>';
        
        return $return;
    }

/*==============================================================================
 * NAVIGATION
==============================================================================*/
    /**
     * A list of tabs
     * 
     * JAVASCRIPT:
     * You can activate individual tabs in several ways:
     * $('#myTab a[href="#profile"]').tab('show'); // Select tab by name
     * $('#myTab a:first').tab('show'); // Select first tab
     * $('#myTab a:last').tab('show'); // Select last tab
     * $('#myTab li:eq(2) a').tab('show'); // Select third tab (0-indexed)
     * Events:
     * $('a[data-toggle="tab"]').on('show/shown', function (e) {
     *  e.target // activated tab
     *  e.relatedTarget // previous tab
     * })
     * 
     * @param type $items   : Array of items containing [text] (title of tab), [style] which can be "disabled" or "active" to indicate the currently active item
     * @param type $tabs    : Array of content/active state/id of tabs. Can be left "false" if the tabs are loading new pages
     * @param string $class
     * @param string $tabs_class
     * CAN BE:
     * tabs-below
     * tabs-left
     * tabs-right
     * 
     * @param boolean $vertical
     * @return string
     */
    static function nav_tabs($items,$tabs=false,$class='',$tabs_class='',$vertical=false) {
        $return = '';
        if ($tabs) {
            $return.= '<div class="tabbable '.$tabs_class.'">';
            /*
            reset($tabs);
            $first_key = key($tabs);
            end($tabs);
            $last_key = key($tabs)+1;
             * 
             */
            //for ($i=(int)$first_key;$i<(int)$last_key;$i++) {
            for ($i=0;$i<count($tabs);$i++) {
                $items[$i]->text = '<a href="#'.$tabs[$i]->id.'" data-toggle="tab">'.$items[$i]->text.'</a>';
            }
        }
        if ($vertical) $class = 'nav-stacked '.$class;
        $class = 'nav nav-tabs '.$class;
        $return.= AFB::list_bulletin($items, $class);
        if ($tabs) {
            $return.= '<div class="tab-content">';
            foreach($tabs as $content) {
                $content->active = !empty($content->active) ? ' active' : ' fade';
                $return.= '<div class="tab-pane'.$content->active.'" id="'.$content->id.'">';
                $return.= $content->content;
                $return.= '<br style="clear:both" />';
                $return.= '</div>';
            }
            $return.= '</div>';
        }
        if ($tabs) $return.= '</div>';
        return $return;
    }

    /**
     * A list of pills
     * 
     * @param type $items   : Array of items containing [title], [disabled] and [active] to indicate the currently active item
     * @param string $class
     * @param boolean $vertical
     * @return string
     */
    static function nav_pills($items,$class='',$vertical=false) {
        $class = 'nav nav-pills '.$class;
        if ($vertical) $class.= ' nav-stacked';
        return AFB::list_bulletin($items, $class);
    }

    /**
     * A vertical navigation list
     * 
     * @param type $items   : Array of items containing [title], [disabled] and [active] to indicate the currently active item
     * @param string $class
     * @param boolean $vertical
     * @return string
     */
    static function nav_list($items,$class='') {
        $class = 'nav nav-list '.$class;
        return AFB::list_bulletin($items, $class);
    }
    
    /**
     * 
     * @param type $title   : title of the navbar. Can be linked
     * @param type $items   : items of the navbar
     * CAN BE:
     * pre-rendered lists
     *      Instead of "divider", use "divider-vertical" here. Use "nav" class for these lists!
     * pre-rendered dropdowns
     *      These lists are rendered like that:
     *     <ul class="nav">
     *      <li class="dropdown">
     *          <a href="#" class="dropdown-toggle" data-toggle="dropdown">
     *              TITLE
     *              <b class="caret"></b>
     *          </a>
     *          <ul class="dropdown-menu">
     *              ...
     *          </ul>
     *      </li>
     *     </ul>
     * pre-rendered forms
     *      Use "navbar-form" class for these forms! If search form, use "navbar-search" to the form and "search-query" to the input for specialized styles in the navbar
     * pre-rendered text
     *      Wrap strings of text in an element with .navbar-text, usually on a <p> tag for proper leading and color.
     * 
     * To align nav links, search form, or text, use the .pull-left or .pull-right utility classes. Both classes will add a CSS float in the specified direction.
     * 
     * @param string $class
     * CAN BE (among others):
     * navbar-fixed-top     : Fixed to top: Add .navbar-fixed-top and remember to account for the hidden area underneath it by adding at least 40px padding to the <body>. Be sure to add this after the core Bootstrap CSS and before the optional responsive CSS.
     * navbar-fixed-bottom  : Fixed to bottom
     * navbar-static-top    : Static top navbar: Create a full-width navbar that scrolls away with the page by adding .navbar-static-top. Unlike the .navbar-fixed-top class, you do not need to change any padding on the body.
     * navbar-inverse       : Black navbar white font: Modify the look of the navbar by adding .navbar-inverse.
     * 
     */
    static function navbar($title,$items,$class='') {
        $return = '<div class="navbar '.$class.'">';
        $return.= '<div class="navbar-inner">';
        $return.= '<div class="container">';
        $return.= ' <!-- .btn-navbar is used as the toggle for collapsed navbar content -->';
        $return.= '<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">';
        $return.= '<span class="icon-bar"></span>';
        $return.= '<span class="icon-bar"></span>';
        $return.= '<span class="icon-bar"></span>';
        $return.= '</a>';
        $return.= '<!-- Be sure to leave the brand out there if you want it shown -->';
        $return.= '<a class="brand" href="#">'.$title.'</a>';
        $return.= '<!-- Everything you want hidden at 940px or less, place within here -->';
        $return.= '<div class="nav-collapse collapse">';
        foreach ($items as $item) {
            $return.= $item;
        }
        $return.= '</div>';
        $return.= '</div>';
        $return.= '</div>';
        $return.= '</div>';
        
        return $return;
    }

/*==============================================================================
 * BREADCRUMBS
==============================================================================*/
    /**
     * 
     * @param type $items
     * @param string $class
     * @return type
     */
    static function breadcrumb($items,$class='') {
        $class = 'breadcrumb '.$class;
        return AFB::list_bulletin($items, $class);
    }
    
/*==============================================================================
 * PAGINATION
==============================================================================*/
    /**
     * 
     * @param type $items
     * @param type $class
     * CAN BE(among others):
     * pagination-large
     * pagination-small
     * pagination-mini
     * pagination-centered
     * pagination-right
     * 
     * @return type
     */
    static function pagination($items,$class='') {
        $return = '<div class="pagination '.$class.'">';
        $return.= (is_array($items) || is_object($items)) ? AFB::list_bulletin($items, $class) : $items;
        $return.= '</div>';
        
        return $return;
    }
    
    /**
     * 
     * @param type $previous
     * ->style: "previous" & "disabled"
     * ->link
     * ->title
     * @param type $next
     * ->style: "next" & "disabled"
     * ->link
     * ->title
     * @param type $class
     * @return string
     */
    static function pager($previous,$next,$class='') {
        $return = '<ul class="pager '.$class.'">';
        $return.= '<li'.$previous->style.'><a href="'.$previous->link.'">&larr; '.$previous->title.'</a></li>';
        $return.= '<li'.$next->style.'><a href="'.$next->link.'">'.$next->title.' &rarr;</a></li>';
        $return.= '</ul>';
        
        return $return;
    }
    
/*==============================================================================
 * LABELS AND BADGES
==============================================================================*/
    /**
     * 
     * @param type $text
     * @param type $class
     * CAN BE (among others):
     * label-success
     * label-warning
     * label-important
     * label-info
     * label-inverse
     * 
     * @return type
     */
    static function label($text,$class='') {
        return '<span class="label '.$class.'">'.$text.'</span>';
    }
    
    /**
     * 
     * @param type $text
     * @param type $class
     * CAN BE (among others):
     * badge-success
     * badge-warning
     * badge-important
     * badge-info
     * badge-inverse
     * 
     * @return type
     */
    static function badge($text,$class='') {
        return '<span class="badge '.$class.'">'.$text.'</span>';
    }
    
/*==============================================================================
 * THUMBNAILS
==============================================================================*/
    /**
     * Thumbnails are great for grids of photos or videos, image search results, retail products, portfolios, and much more. They can be links or static content.
     * By default, Bootstrap's thumbnails are designed to showcase linked images with minimal required markup.
     * With a bit of extra markup, it's possible to add any kind of HTML content like headings, paragraphs, or buttons into thumbnails.
     * Thumbnail markup is simple—a ul with any number of li elements is all that is required. It's also super flexible, allowing for any type of content with just a bit more markup to wrap your contents.
     * Lastly, the thumbnails component uses existing grid system classes—like .span2 or .span3—for control of thumbnail dimensions.
     * 
     * @param type $thumbnails  => array of thumbnail objects ([size], [content])
     * @param type $class
     * @return string
     */
    static function thumbnails($thumbnails,$class='') {
        $return = '<ul class="thumbnails '.$class.'">';
        foreach ($thumbnails as $thumbnail) {
            $return.= '<li class="span'.$thumbnail->size.'">';
            $return.= '<div class="thumbnail">';
            $return.= $thumbnail->content;
            $return.= '</div>';
            $return.= '</li>';
        }
        $return.= '</ul>';
        
        return $return;
    }
    
/*==============================================================================
 * ALERTS
==============================================================================*/
    /**
     * JAVASCRIPT:
     * Close an alert:
     * $(".alert").alert('close')
     * Events:
     * $('#my-alert').bind('close/closed', function () {
     *  // do something…
     * })
     * 
     * @param type $content
     * @param type $class
     * CAN BE (among others):
     * alert-error
     * alert-success
     * alert-info
     * 
     * @return string
     */
    static function alert($content,$class='') {
        $return = '<div class="alert alert-block fade in '.$class.'">';
        $return.= '<button type="button" class="close" data-dismiss="alert">&times;</button>';
        $return.= $content;
        $return.= '</div>';
        
        return $return;
    }
    
/*==============================================================================
 * PROGRESS BARS
==============================================================================*/
    /**
     * 
     * @param type $complete    : the percentage of completion of the progress bar
     * @param type $class
     * CAN BE (among others)
     * progress-striped : Uses a gradient to create a striped effect. Not available in IE7-8.
     * active           : Add .active to .progress-striped to animate the stripes right to left. Not available in all versions of IE.
     *      
     * progress-info
     * progress-success
     * progress-warning
     * progress-danger
     * 
     * @return string
     */
    static function progress_bar($complete,$class='') {
        $return = '<div class="progress '.$class.'">';
        $return.= '<div class="bar" style="width: '.$complete.'%;"></div>';
        $return.= '</div>';
        
        return $return;
    }
    
/*==============================================================================
 * MEDIA OBJECTS
==============================================================================*/
    /**
     * Abstract object styles for building various types of components (like blog comments, Tweets, etc) that feature a left- or right-aligned image alongside textual content.
     * The default media allow to float a media object (images, video, audio) to the left or right of a content block.
     * 
     * @param type $media   : object containing [link] and [object]
     * @param type $text
     * @param type $class
     * @return string
     */
    static function media_object($media,$text,$class='') {
        if (empty($media->link)) $media->link = 'javascript:void(0)';
        $return = '<div class="row media '.$class.'">';
        $return.= '<med class="pull-left"><a href="'.$media->link.'">';
        $return.= $media->object;
        $return.= '</a></med>';
        $return.= '<med class="media-body pull-left">';
        $return.= $text;
        $return.= '</med>';
        $return.= '</div>';
        
        return $return;
    }
    
    /**
     * A list of media-objects
     * 
     * @param type $objects
     * @param string $class
     * @return type
     */
    static function media_list($objects,$class='') {
        $class = 'media-list '.$class;
        return AFB::list_bulletin($objects,$class);
    }
    
/*==============================================================================
 * MISCELLANEOUS
==============================================================================*/
    /**
     * Use the well as a simple effect on an element to give it an inset effect.
     * 
     * @param type $text
     * @param type $class
     * CAN BE (among others):
     * well-large
     * well-small
     * 
     * @return type
     */
    static function well($text,$class='') {
        return '<div class="well '.$class.'">'.$text.'</div>';
    }
    
    /**
     * Use the generic close icon for dismissing content like modals and alerts.
     * 
     * @param type $action  : Javascript. If some action is needed upon clicking add it here
     * @return type
     */
    static function close_icon($action) {
        return '<button onclick="'.$action.'" class="close">&times;</button>';
    }
    
    /**
     * 
     * @param type $title : the contents of the tooltip
     * @param type $text  : the text associated with the tooltip
     * @param type $placement   : top, right, bottom, or left
     * @return type
     */
    static function tooltip($title,$text,$class='',$placement='top') {
        return '<span class="hasTooltip '.$class.'" data-toggle="tooltip" data-placement="'.$placement.'" data-original-title="'.$title.'">'.$text.'</a>';
    }
    
    /**
     * 
     * @param type $title       : the title of the popover
     * @param type $text        : the text of the popover
     * @param type $button      : the element to insert the popover to
     * @param type $placement   : top, right, bottom, or left
     * @return type
     */
    static function popover($title,$text,$element,$placement='top') {
        $id = explode('id="',$element);
        $id = explode('"',$id[1]);
        $id = $id[0];
        ?>
        <script>
        $(function ()
        { $("#<?php echo $id; ?>").popover();
        });
        </script>
        <?php
        return AF_helper::str_replace_first(' id="', ' rel="popover" title="" data-content="'.$text.'" data-placement="'.$placement.'" data-toggle="popover" data-original-title="'.$title.'" id="', $element);
    }
    
/*==============================================================================
 * MODAL BOX
==============================================================================*/
    /**
     * Modals are streamlined, but flexible, dialog prompts with the minimum required functionality and smart defaults.
     * Toggle a modal via JavaScript or by clicking a button. It will slide down and fade in from the top of the page.
     * 
     * Javascript Options:
     * Manually toggles a modal :     $('#myModal').modal('toggle')
     * Manually opens a modal   :     $('#myModal').modal('show')
     * Manually hides a modal   :     $('#myModal').modal('hide')
     * 
     * Events:
     * $('#myModal').on('show/shown/hide/hidden', function () {
     * // do something…
     * })
     * 
     * @param type $id      : the ID of the modal box
     * @param type $button  : the caption of the button. If no caption is given, only the modal box will be created which then you can call by "$('#myModal').modal(options)" (javascript)
     * @param type $title   : the title of the modal box
     * @param type $content : the content of the modal box
     * @param type $footer  : the footer of the modal box
     * @param type $remote  : If a remote url is provided, content will be loaded via jQuery's load method and injected into the .modal-body. If you're using the data api, you may alternatively use the href tag to specify the remote source. An example of this is shown below:
     * @return string
     */
    static function modal_box($id,$button,$title,$content,$footer,$remote=false) {
        $return = '';
        if (!$button) $return = '<a href="#'.$id.'" role="button" class="btn" data-toggle="modal">Launch demo modal'.$button.'</a>';
        if ($remote)  $return = '<a data-toggle="modal" href="'.$remote.'" data-target="#'.$id.'">'.$button.'</a>';
        else {
            $return.= '<div id="'.$id.'" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="'.$id.'Label" aria-hidden="true">';
            $return.= '<div class="modal-header">';
            $return.= '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>';
            $return.= '<h3 id="'.$id.'Label">'.$title.'</h3>';
            $return.= '</div>';
            $return.= '<div class="modal-body">';
            $return.= $content;
            $return.= '</div>';
            $return.= '<div class="modal-footer">';
            $return.= $footer;
            $return.= '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>';
            $return.= '</div>';
            $return.= '</div>';
        }
        return $return;
    }
    
/*==============================================================================
 * ACCORDION
==============================================================================*/
    /**
     * JAVASCRIPT:
     * .collapse('toggle') : Toggles a collapsible element to shown or hidden.
     * .collapse('show')   : Shows a collapsible element.
     * .collapse('hide')   : Hides a collapsible element.
     * Events:
     * $('#myCollapsible').on('show/shown/hide/hidden', function () {
     *  // do something…
     * })
     * 
     * @param type $id    : accordion ID
     * @param type $items : accordion items | title/content
     * @param type $class : accordion extra class
     * @return string
     */
    static function accordion($id,$items,$class='') {
        $return = '<div class="accordion '.$class.'" id="'.$id.'">';
        $i=1;
        foreach ($items as $item) {
            $return.= '<div class="accordion-group">';
            $return.= '<div class="accordion-heading">';
            $return.= '<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2'.$id.'" href="#'.$id.$i.'">';
            $return.= $item->title;
            $return.= '</a>';
            $return.= '</div>';
            $return.= '<div id="'.$id.$i.'" class="accordion-body collapse in">';
            $return.= '<div class="accordion-inner">';
            $return.= $item->content;
            $return.= '</div>';
            $return.= '</div>';
            $return.= '</div>';
            $i++;
        }
        $return.= '</div>';

        return $return;
    }
    

/*==============================================================================
 * CAROUSEL
==============================================================================*/
    /**
     * JAVASCRIPT:
     * .carousel('cycle') : Cycles through the carousel items from left to right.
     * .carousel('pause') : Stops the carousel from cycling through items.
     * .carousel(number)  : Cycles the carousel to a particular frame (0 based, similar to an array).
     * .carousel('prev')  : Cycles to the previous item.
     * .carousel('next')  : Cycles to the next item.
     * Events:
     * slide/slid
     * 
     * @param type $id       : carousel ID
     * @param type $items    : carousel items | image/caption
     * @param type $class    : carouser extra class
     * @param type $interval : The amount of time to delay between automatically cycling an item. If 'false', carousel will not automatically cycle.
     * @param type $pause    : Pauses the cycling of the carousel on mouseenter and resumes the cycling of the carousel on mouseleave. Default is TRUE
     */
    static function carousel($id,$items,$class='',$interval=5000) {
        $return = '<div class="carousel slide '.$class.'" data-interval="'.$interval.'" id="'.$id.'">';
        $return.= '<ol class="carousel-indicators">';
        $i=0;
        foreach ($items as $item) {
            $return.= '<li data-target="#'.$id.'" data-slide-to="'.$i.'"></li>';
            $i++;
        }
        $return.= '</ol>';
        $return.= '<div class="carousel-inner">';
        foreach ($items as $item) {
            $return.= '<div class="item">';
            $return.= '<img src="'.$item->image.'">';
            if (!empty($item->caption)) {
                $return.= '<div class="carousel-caption">';
                $return.= $item->caption;
                $return.= '</div>';
            }
            $return.= '</div>';
        }
        $return.= '<a class="left carousel-control" href="#'.$id.'" data-slide="prev">‹</a>';
        $return.= '<a class="right carousel-control" href="#'.$id.'" data-slide="next">›</a>';
    }
                
}
